/*-
 * DCS.java          TP-Data-Coding-Scheme (TP-DCS)
 *
 * $LastChangedBy: stein $
 * $LastChangedRevision: 95 $
 * $LastChangedDate: 2007-02-13 16:19:24 +0000 (Tue, 13 Feb 2007) $
 * $HeadURL: svn://localhost/SMS/src/com/googlecode/attention/sms/pdu/DCS.java $
 *
 * Copyright (c) 2007, Stein Gunnar Bakkeby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Stein Gunnar Bakkeby nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.attention.sms.pdu;

import com.googlecode.attention.util.IntValue;

import static com.googlecode.attention.util.bit.ByteBitValues.*;

/**
 * TP-Data-Coding-Scheme.
 * <BR>
 * The TP-Data-Coding-Scheme field, defined in 3GPP TS 23.040,
 * indicates the data coding scheme of the TP-UD field, and may
 * indicate a message class. Any reserved codings shall be assumed
 * to be the GSM 7 bit default alphabet (the same as codepoint 00000000)
 * by a receiving entity. The octet is used according to a coding group
 * which is indicated in bits 7..4. The octet is then coded as follows:
 * <BR>
 * <BR>
 * <TABLE BORDER="1">
 * <TR><TD>Coding Group Bits 7..4</TD><TD>Use of bits 3..0</TD></TR>
 * <TR><TD>00xx</TD>
 *     <TD>General Data Coding indication
 *         <BR>Bits 5..0 indicate the following:
 *         <BR>
 *         <BR>Bit 5, if set to 0, indicates the text is uncompressed
 *         <BR>Bit 5, if set to 1, indicates the text is compressed using
 *             the compression algorithm defined in 3GPP TS 23.042.
 *         <BR>
 *         <BR>Bit 4, if set to 0, indicates that bits 1 to 0 are reserved
 *             and have no message class meaning
 *         <BR>Bit 4, if set to 1, indicates that bits 1 to 0 have a message
 *             class meaning:
 *         <BR>
 *         <BR><TABLE>
 *             <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Message Class</TD></TR>
 *             <TR><TD>0</TD><TD>0</TD><TD>Class 0</TD></TR>
 *             <TR><TD>0</TD><TD>1</TD><TD>Class 1 Default meaning: ME-specific.</TD></TR>
 *             <TR><TD>1</TD><TD>0</TD><TD>Class 2 (U)SIM specific message</TD></TR>
 *             <TR><TD>1</TD><TD>1</TD><TD>Class 3 Default meaning: TE specific (see 3GPP TS 27.005 [8])</TD></TR>
 *             </TABLE>
 *         <BR>
 *         <BR>Bits 3 and 2 indicate the character set being used, as follows:
 *         <BR><TABLE>
 *             <TR><TD>Bit 3</TD><TD>Bit2</TD><TD>Character set:</TD></TR>
 *             <TR><TD>0</TD><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
 *             <TR><TD>0</TD><TD>1</TD><TD>8 bit data</TD></TR>
 *             <TR><TD>1</TD><TD>0</TD><TD>UCS2 (16bit)</TD></TR>
 *             <TR><TD>1</TD><TD>1</TD><TD>Reserved</TD></TR>
 *             </TABLE>
 *         <BR>
 *         <BR>NOTE: The special case of bits 7..0 being 0000 0000 indicates
 *             the GSM 7 bit default alphabet with no message class.
 *     </TD>
 * </TR>
 * <TR><TD>01xx</TD>
 *     <TD>Message Marked for Automatic Deletion Group
 *     <BR>
 *     <BR>This group can be used by the SM originator to mark the message
 *         ( stored in the ME or (U)SIM ) for deletion after reading
 *         irrespective of the message class.
 *     <BR>The way the ME will process this deletion should be manufacturer
 *         specific but shall be done without the intervention of the End
 *         User or the targeted application. The mobile manufacturer may
 *         optionally provide a means for the user to prevent this automatic
 *         deletion.
 *     <BR>
 *     <BR>Bit 5..0 are coded exactly the same as Group 00xx
 *     </TD>
 * </TR>
 * <TR><TD>1000..1011</TD><TD>Reserved coding groups</TD></TR>
 * <TR><TD>1100</TD>
 *     <TD>Message Waiting Indication Group: Discard Message
 *     <BR>
 *     <BR>The specification for this group is exactly the same as for
 *         Group 1101, except that:
 *     <BR>- after presenting an indication and storing the status, the
 *         ME may discard the contents of the message.
 *     <BR>
 *     <BR>The ME shall be able to receive, process and acknowledge
 *         messages in this group, irrespective of memory availability
 *         for other types of short message.
 *     </TD>
 * </TR>
 * <TR><TD>1101</TD>
 *     <TD>Message Waiting Indication Group: Store Message
 *     <BR>
 *     <BR>This Group defines an indication to be provided to the user
 *         about the status of types of message waiting on systems connected
 *         to the GSM/UMTS PLMN. The ME should present this indication as an
 *         icon on the screen, or other MMI indication. The ME shall update
 *         the contents of the Message Waiting Indication Status on the SIM
 *         (see 3GPP TS 51.011) or USIM (see 3GPP TS 31.102) when present or
 *         otherwise should store the status in the ME. In case there are
 *         multiple records of EFMWIS this information should be stored within
 *         the first record. The contents of the Message Waiting Indication
 *         Status should control the ME indicator. For each indication
 *         supported, the mobile may provide storage for the Origination
 *         Address. The ME may take note of the Origination Address for
 *         messages in this group and group 1100.
 *     <BR>
 *     <BR>Text included in the user data is coded in the GSM 7 bit default
 *         alphabet.
 *     <BR>Where a message is received with bits 7..4 set to 1101, the
 *         mobile shall store the text of the SMS message in addition to
 *         setting the indication. The indication setting should take place
 *         irrespective of memory availability to store the short message.
 *     <BR>
 *     <BR>Bits 3 indicates Indication Sense:
 *     <BR>Bit 3
 *     <BR><TABLE>
 *         <TR><TD>0</TD><TD>Set Indication Inactive</TD></TR>
 *         <TR><TD>1</TD><TD>Set Indication Active</TD></TR>
 *         </TABLE>
 *     <BR>
 *     <BR>Bit 2 is reserved, and set to 0
 *     <BR>
 *     <BR><TABLE>
 *         <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Indication Type:</TD></TR>
 *         <TR><TD>0</TD><TD>0</TD><TD>Voicemail Message Waiting</TD></TR>
 *         <TR><TD>0</TD><TD>1</TD><TD>Fax Message Waiting</TD></TR>
 *         <TR><TD>1</TD><TD>0</TD><TD>Electronic Mail Message Waiting</TD></TR>
 *         <TR><TD>1</TD><TD>1</TD><TD>Other Message Waiting*</TD></TR>
 *         </TABLE>
 *     <BR>
 *     <BR>* Mobile manufacturers may implement the "Other Message Waiting"
 *           indication as an additional indication without specifying the
 *           meaning. The meaning of this indication is intended to be
 *           standardized in the future, so Operators should not make use of
 *           this indication until the standard for this indication is
 *           finalized.
 *     </TD>
 * </TR>
 * <TR><TD>1110</TD>
 *     <TD>Message Waiting Indication Group: Store Message
 *     <BR>
 *     <BR>The coding of bits 3..0 and functionality of this feature are
 *         the same as for the Message Waiting Indication Group above,
 *         (bits 7..4 set to 1101) with the exception that the text included
 *         in the user data is coded in the uncompressed UCS2 character set.
 *     </TD>
 * </TR>
 * <TR><TD>1111</TD>
 *     <TD>Data coding/message class
 *     <BR>
 *     <BR>Bit 3 is reserved, set to 0.
 *     <BR>
 *     <BR><TABLE>
 *         <TR><TD>Bit 2</TD><TD>Message coding:</TD></TR>
 *         <TR><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
 *         <TR><TD>1</TD><TD>8-bit data</TD></TR>
 *         </TABLE>
 *     <BR>
 *     <BR><TABLE>
 *         <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Message Class:</TD></TR>
 *         <TR><TD>0</TD><TD>0</TD><TD>Class 0</TD></TR>
 *         <TR><TD>0</TD><TD>1</TD><TD>Class 1 default meaning: ME-specific.</TD></TR>
 *         <TR><TD>1</TD><TD>0</TD><TD>Class 2 (U)SIM-specific message.</TD></TR>
 *         <TR><TD>1</TD><TD>1</TD><TD>Class 3 default meaning: TE specific (see 3GPP TS 27.005)</TD></TR>
 *         </TABLE>
 *     </TD>
 * </TR>
 * </TABLE>
 * <BR>
 * <BR>GSM 7 bit default alphabet indicates that the TP-UD is coded from the
 * GSM 7 bit default alphabet given in clause 6.2.1. When this character set
 * is used, the characters of the message are packed in octets as shown in
 * clause 6.1.2.1.1 (in 3GPP TS 23.038 version 5.1.0 Release 5), and the
 * message can consist of up to 160 characters. The GSM 7 bit default alphabet
 * shall be supported by all MSs and SCs offering the service. If the GSM 7
 * bit default alphabet extension mechanism is used then the number of
 * displayable characters will reduce by one for every instance where the
 * GSM 7 bit default alphabet extension table is used. 8-bit data indicates
 * that the TP-UD has user-defined coding, and the message can consist of up
 * to 140 octets.
 * <BR>
 * <BR>UCS2 character set indicates that the TP-UD has a UCS2 coded message,
 * and the message can consist of up to 140 octets, i.e. up to 70 UCS2
 * characters. The General notes specified in clause 6.1.1 override any
 * contrary specification in UCS2, so for example even in UCS2 a &lt;CR&gt;
 * character will cause the MS to return to the beginning of the current line
 * and overwrite any existing text with the characters which follow the
 * &lt;CR&gt;.
 * <BR>
 * <BR>When a message is compressed, the TP-UD consists of the GSM 7 bit
 * default alphabet or UCS2 character set compressed message, and the
 * compressed message itself can consist of up to 140 octets in total.
 * <BR>
 * <BR>When a mobile terminated message is class 0 and the MS has the
 * capability of displaying short messages, the MS shall display the message
 * immediately and send an acknowledgement to the SC when the message has
 * successfully reached the MS irrespective of whether there is memory
 * available in the (U)SIM or ME. The message shall not be automatically
 * stored in the (U)SIM or ME.
 * <BR>
 * <BR>The ME may make provision through MMI for the user to selectively
 * prevent the message from being displayed immediately.
 * <BR>
 * <BR>If the ME is incapable of displaying short messages or if the immediate
 * display of the message has been disabled through MMI then the ME shall
 * treat the short message as though there was no message class, i.e. it will
 * ignore bits 0 and 1 in the TP-DCS and normal rules for memory capacity
 * exceeded shall apply.
 * <BR>
 * <BR>When a mobile terminated message is Class 1, the MS shall send an
 * acknowledgement to the SC when the message has successfully reached the MS
 * and can be stored. The MS shall normally store the message in the ME by
 * default, if that is possible, but otherwise the message may be stored
 * elsewhere, e.g. in the (U)SIM. The user may be able to override the default
 * meaning and select their own routing.
 * <BR>
 * <BR>When a mobile terminated message is Class 2 ((U)SIM-specific), an MS
 * shall ensure that the message has been transferred to the SMS data field
 * in the (U)SIM before sending an acknowledgement to the SC. The MS shall
 * return a "protocol error, unspecified" error message (see 3GPP TS 24.011)
 * if the short message cannot be stored in the (U)SIM and there is other
 * short message storage available at the MS. If all the short message
 * storage at the MS is already in use, the MS shall return "memory capacity
 * exceeded". This behaviour applies in all cases except for an MS supporting
 * (U)SIM Application Toolkit when the Protocol Identifier (TP-PID) of the
 * mobile terminated message is set to "(U)SIM Data download" (see 3GPP TS
 * 23.040).
 * <BR>
 * <BR>When a mobile terminated message is Class 3, the MS shall send an
 * acknowledgement to the SC when the message has successfully reached the MS
 * and can be stored, irrespectively of whether the MS supports an SMS
 * interface to a TE, and without waiting for the message to be transferred
 * to the TE. Thus the acknowledgement to the SC of a TE-specific message does
 * not imply that the message has reached the TE. Class 3 messages shall
 * normally be transferred to the TE when the TE requests "TE-specific"
 * messages (see 3GPP TS 27.005). The user may be able to override the default
 * meaning and select their own routing.
 * <BR>
 * <BR>The message class codes may also be used for mobile originated messages,
 * to provide an indication to the destination SME of how the message was
 * handled at the MS.
 * <BR>
 * <BR>The MS will not interpret reserved or unsupported values but shall store
 * them as received. The SC may reject messages with a Data Coding Scheme
 * containing a reserved value or one which is not supported.
 * <BR>
 * <BR>
 * <BR><A HREF="http://www.dreamfabric.com/sms/dcs.html">
 *              http://www.dreamfabric.com/sms/dcs.html</A>
 *
 * @author Stein Gunnar Bakkeby
 */
public class DCS extends IntValue {
  
  /* Static field values */
  /* Groups - bits 7 to 4 */
  /**
   * General Data Coding indication.
   * <BR>
   * <BR>Bits 5..0 indicate the following:
   * <BR>
   * <BR>Bit 5, if set to 0, indicates the text is uncompressed
   * <BR>Bit 5, if set to 1, indicates the text is compressed using
   *     the compression algorithm defined in 3GPP TS 23.042.
   * <BR>
   * <BR>Bit 4, if set to 0, indicates that bits 1 to 0 are reserved
   *     and have no message class meaning
   * <BR>Bit 4, if set to 1, indicates that bits 1 to 0 have a message
   *     class meaning:
   * <BR>
   * <BR><TABLE>
   * <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Message Class</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>Class 0</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>Class 1 Default meaning: ME-specific.</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>Class 2 (U)SIM specific message</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Class 3 Default meaning: TE specific (see 3GPP TS 27.005 [8])</TD></TR>
   * </TABLE>
   * <BR>
   * <BR>Bits 3 and 2 indicate the character set being used, as follows:
   * <BR><TABLE>
   * <TR><TD>Bit 3</TD><TD>Bit2</TD><TD>Character set:</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>8 bit data</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>UCS2 (16bit)</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Reserved</TD></TR>
   * </TABLE>
   * <BR>
   * <BR>NOTE: The special case of bits 7..0 being 0000 0000 indicates
   *     the GSM 7 bit default alphabet with no message class.
   */
  public static final int GROUP_GENERAL_DATA_CODING = 0; // 00xx
  /**
   * Message Marked for Automatic Deletion Group.
   * <BR>
   * <BR>This group can be used by the SM originator to mark the message
   * ( stored in the ME or (U)SIM ) for deletion after reading irrespective
   * of the message class. The way the ME will process this deletion should
   * be manufacturer specific but shall be done without the intervention of
   * the End User or the targeted application.The mobile manufacturer may
   * optionally provide a means for the user to prevent this automatic
   * deletion.
   * <BR>
   * <BR>Bit 5..0 are coded exactly the same as Group 00xx
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   */
  public static final int GROUP_AUTOMATIC_DELETION = 0x40; // B6 - 01xx
  /** Reserved coding group. */
  public static final int GROUP_RESERVED_1000 = 0x80; // B7 - 1000
  /** Reserved coding group. */
  public static final int GROUP_RESERVED_1001 = 0x90; // B7|B4 - 1001
  /** Reserved coding group. */
  public static final int GROUP_RESERVED_1010 = 0xA0; // B7|B5 - 1010
  /** Reserved coding group. */
  public static final int GROUP_RESERVED_1011 = 0xB0; // B7|B5|B4 - 1011
  /**
   * Message Waiting Indication Group: Discard Message.
   * <BR>
   * <BR>The specification for this group is exactly the same as for
   * Group 1101, except that:
   * <BR> - after presenting an indication and storing the status,
   * the ME may discard the contents of the message.
   * <BR>
   * <BR>The ME shall be able to receive, process and acknowledge messages
   * in this group, irrespective of memory availability for other types
   * of short message.  
   * 
   * @see #GROUP_MESSAGE_WAITING_STORE
   */
  public static final int GROUP_MESSAGE_WAITING_DISCARD = 0xC0; // B7|B6 - 1100
  /**
   * Message Waiting Indication Group: Store Message.
   * <BR>
   * <BR>This Group defines an indication to be provided to the user
   * about the status of types of message waiting on systems connected
   * to the GSM/UMTS PLMN. The ME should present this indication as an
   * icon on the screen, or other MMI indication. The ME shall update
   * the contents of the Message Waiting Indication Status on the SIM
   * (see 3GPP TS 51.011) or USIM (see 3GPP TS 31.102) when present or
   * otherwise should store the status in the ME. In case there are
   * multiple records of EFMWIS this information should be stored within
   * the first record. The contents of the Message Waiting Indication
   * Status should control the ME indicator. For each indication
   * supported, the mobile may provide storage for the Origination
   * Address. The ME may take note of the Origination Address for
   * messages in this group and group 1100.
   * <BR>
   * <BR>Text included in the user data is coded in the GSM 7 bit default
   * alphabet.
   * <BR>Where a message is received with bits 7..4 set to 1101, the
   * mobile shall store the text of the SMS message in addition to
   * setting the indication. The indication setting should take place
   * irrespective of memory availability to store the short message.
   * <BR>
   * <BR>Bits 3 indicates Indication Sense:
   * <BR>Bit 3
   * <BR>
   * <TABLE>
   * <TR><TD>0</TD><TD>Set Indication Inactive</TD></TR>
   * <TR><TD>1</TD><TD>Set Indication Active</TD></TR>
   * </TABLE>
   * <BR>
   * <BR>Bit 2 is reserved, and set to 0
   * <BR>
   * <BR>
   * <TABLE>
   * <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Indication Type:</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>Voicemail Message Waiting</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>Fax Message Waiting</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>Electronic Mail Message Waiting</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Other Message Waiting*</TD></TR>
   * </TABLE>
   * 
   * @see #MESSAGE_WAITING_OTHER
   */
  public static final int GROUP_MESSAGE_WAITING_STORE = 0xD0; // B7|B6|B4;
  /**
   * Message Waiting Indication Group: Store Message.
   * <BR>
   * <BR>The coding of bits 3..0 and functionality of this feature are
   * the same as for the Message Waiting Indication Group above,
   * (bits 7..4 set to 1101) with the exception that the text included in
   * the user data is coded in the uncompressed UCS2 character set.
   * 
   * @see #GROUP_MESSAGE_WAITING_STORE
   */
  public static final int GROUP_MESSAGE_WAITING_STORE_UCS2 = 0xE0; // B7|B6|B5
  /**
   * Data coding/message class.
   * <BR>
   * <BR>Bit 3 is reserved, set to 0.
   * <BR>
   * <BR>
   * <TABLE>
   * <TR><TD>Bit 2</TD><TD>Message coding:</TD></TR>
   * <TR><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
   * <TR><TD>1</TD><TD>8-bit data</TD></TR>
   * </TABLE>
   * <BR>
   * <BR>
   * <TABLE>
   * <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Message Class:</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>Class 0</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>Class 1 default meaning: ME-specific.</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>Class 2 (U)SIM-specific message.</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Class 3 default meaning: TE specific (see 3GPP TS 27.005)</TD></TR>
   * </TABLE>
   */
  public static final int GROUP_MESSAGE_CODING_CLASS = 0xF0; //B7|B6|B5|B4 1111
  
  /* Message Class - bits 1 and 0 */
  /** Class 0 */
  public static final int MESSAGE_CLASS_0                  =  0x0; //       00
  /** Class 1 Default meaning: ME-specific. */
  public static final int MESSAGE_CLASS_1                  =  0x1; // B0  - 01
  /** Class 2 (U)SIM specific message. */
  public static final int MESSAGE_CLASS_2                  =  0x2; // B1  - 10
  /** Class 3 Default meaning: TE specific (see 3GPP TS 27.005). */
  public static final int MESSAGE_CLASS_3                  =  0x3; // B1|B0-11
  
  /* Message Waiting - bits 1 and 0 */
  /** Voicemail Message Waiting. */
  public static final int MESSAGE_WAITING_VOICEMAIL        =  0x0; //      00
  /** Fax Message Waiting. */
  public static final int MESSAGE_WAITING_FAX              =  0x1; // B0 - 01
  /** Electronic Mail Message Waiting. */
  public static final int MESSAGE_WAITING_ELECTRONIC_MAIL  =  0x2; // B1 - 10
  /**
   * Other Message Waiting*.
   * <BR>
   * <BR>*Mobile manufacturers may implement the "Other Message Waiting"
   * indication as an additional indication without specifying the meaning.
   * The meaning of this indication is intended to be standardised in the
   * future, so Operators should not make use of this indication until the
   * standard for this indication is finalised.
   */
  public static final int MESSAGE_WAITING_OTHER        =  0x3; // B1|B0 - 11
  
  /* Message Coding - bits 3 and 2 */
  /** GSM 7 bit default alphabet. */
  public static final int MESSAGE_CODING_7_BIT_DEFAULT =  0x0; //         00
  /** 8 bit data. */
  public static final int MESSAGE_CODING_8_BIT_DATA    =  0x4; // B2    - 01
  /** UCS2 (16bit). */
  public static final int MESSAGE_CODING_UCS2          =  0x8; // B3    - 10
  /** Reserved. */
  public static final int MESSAGE_CODING_RESERVED      =  0xC; // B3|B2 - 11
  /* End static field values */  
    
  /** Inherited constructor from IntValue. */
  public DCS() {
    super(0);
  }
  
  /**
   * Inherited constructor from IntValue.
   * @param value The value of this object
   */
  public DCS(final int value) {
    super(value);
  }
  
  /**
   * Inherited constructor from IntValue.
   * @param hex The value of this object in hex
   */
  public DCS(final String hex) {
    super(hex);
  }
  
  /**
   * This will return the DCS group, see GROUP_ field values.
   * 
   * @return The group, see static field values
   */
  public int getGroup() {
    int int7to6 = value & 0xC0; // (B7|B6)
    
    switch (int7to6) {
    case GROUP_GENERAL_DATA_CODING: // 00xx
    case GROUP_AUTOMATIC_DELETION:  // 01xx
      return int7to6;
      
    default: // any other group
      return value & 0xF0; // (B7|B6|B5|B4) == 1xxx
    }
  }
  
  /**
   * This will tell if the text is compressed or not and it will
   * return false if the DCS group is one that does not support
   * compression.
   * <BR>
   * <BR>The compression algorithm is defined in 3GPP TS 23.042.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @return True if text is compressed, false otherwise
   */
  public boolean isTextCompressed() {
    switch (value & 0xC0) { // (B7|B6)
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:
      return (value & 0x20) != 0; // B5
      
    default: // any other group
      return false;
    }
  }
  
  /**
   * This indicates that bits 1 and 0 have a class meaning. 
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * <BR> - GROUP_MESSAGE_CODING_CLASS (always)
   * <BR>
   * <BR>Bit 4, if set to 0, indicates that bits 1 to 0 are reserved
   * and have no message class meaning.
   * <BR>
   * <BR>Bit 4, if set to 1, indicates that bits 1 to 0 have
   * a message class meaning.
   * <BR>
   * <BR>
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @see #GROUP_MESSAGE_CODING_CLASS
   * @see #getClassMeaning()
   * @return True if DCS has class meaning
   */
  public boolean hasClassMeaning() {
    switch (getGroup()) {
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:
      return (value & 0x10) != 0; // B4
      
    case GROUP_MESSAGE_CODING_CLASS:
      return true; // assumed always class meaning with group 1111
    
    default: // all other groups
      return false;
    }
  }
  
  /**
   * This will return the class meaning, see MESSAGE_CLASS_ field values.
   * <BR>
   * <BR>Note that this method does not check whether the DCS has
   * a class meaning.
   * <BR>
   * <BR><TABLE>
   * <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Message Class</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>Class 0: Immediate display (alert)</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>Class 1: ME specific.</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>Class 2: (U)SIM specific message</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Class 3: TE specific (see 3GPP TS 27.005 [8])</TD></TR>
   * </TABLE>
   * 
   * @see #hasClassMeaning()
   * @return Integer representing bits 1 and 0
   */
  public int getClassMeaning() {
    return value & 0x3; // (B1|B0)
  }
    
  /**
   * This will return the message coding used,
   * see MESSAGE_CODING_ field values.
   * <BR>
   * <BR>All reserved groups are expected to use the
   * GSM 7-bit default alphabet.
   * <BR> 
   * <BR>GROUP_MESSAGE_WAITING_DISCARD and GROUP_MESSAGE_WAITING_STORE
   * <BR> - Character set used: GSM 7bit default alphabet
   * <BR>
   * <BR>GROUP_MESSAGE_WAITING_STORE_UCS2
   * <BR> - Character set used: UCS2 (uncompressed)
   * <BR>  
   * <BR>GROUP_MESSAGE_CODING_CLASS:
   * <BR> - Bit 2 indicates the character set used.
   * <BR><BR><TABLE>
   * <TR><TD>Bit2</TD><TD>Character set:</TD></TR>
   * <TR><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
   * <TR><TD>1</TD><TD>8 bit data</TD></TR>
   * </TABLE>
   * <BR>
   * <BR>GROUP_GENERAL_DATA_CODING and GROUP_AUTOMATIC_DELETION:
   * <BR> - Bits 3 and 2 indicate the character set being used, as follows:
   * <BR><BR><TABLE>
   * <TR><TD>Bit 3</TD><TD>Bit2</TD><TD>Character set:</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>GSM 7 bit default alphabet</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>8 bit data</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>UCS2 (16bit)</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Reserved</TD></TR>
   * </TABLE>
   * 
   * @return See MESSAGE_CODING_ field values
   */
  public int getMessageCoding() {
    switch (getGroup()) {
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:
      /* Bits 3 and 2 indicate the character set used. */
      return value & 0xC; // (B3|B2)
      
    case GROUP_MESSAGE_CODING_CLASS:
      /* Bit 2 indicates the character set used. */
      return value & 0x8; // B3
      
    case GROUP_MESSAGE_WAITING_STORE_UCS2:
      return MESSAGE_CODING_UCS2;
      
    case GROUP_MESSAGE_WAITING_DISCARD:
    case GROUP_MESSAGE_WAITING_STORE:
      return MESSAGE_CODING_7_BIT_DEFAULT;
    
    default: // all other groups (i.e. reserved groups)
      return MESSAGE_CODING_7_BIT_DEFAULT;
    }
  }
  
  /**
   * This will return true if indication is active, false if indication
   * is inactive, and false if the specified coding group does not include
   * indication.
   * <BR>
   * <BR>Bits 3 indicates Indication Sense:
   * <BR>Bit 3
   * <BR>
   * <TABLE>
   * <TR><TD>0</TD><TD>Set Indication Inactive</TD></TR>
   * <TR><TD>1</TD><TD>Set Indication Active</TD></TR>
   * </TABLE>
   * <BR>
   * 
   * @see #GROUP_MESSAGE_WAITING_DISCARD
   * @see #GROUP_MESSAGE_WAITING_STORE
   * @see #GROUP_MESSAGE_WAITING_STORE_UCS2
   * @see #getIndicationType()
   * @return True if indication is active, false otherwise
   */
  public boolean isIndicationActive() {
    switch (getGroup()) {
    case GROUP_MESSAGE_WAITING_DISCARD:
    case GROUP_MESSAGE_WAITING_STORE:
    case GROUP_MESSAGE_WAITING_STORE_UCS2:
      return (value & 0x8) != 0; // B3
    
    default: // all other groups
      return false;
    }
  }
  
  /**
   * This will return the indication type, see MESSAGE_WAITING_ field values.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_MESSAGE_WAITING_DISCARD
   * <BR> - GROUP_MESSAGE_WAITING_STORE
   * <BR> - GROUP_MESSAGE_WAITING_STORE_UCS2
   * <BR>
   * <BR>Note that this method does not check whether the DCS are
   * in one of these coding groups, it merely returns the value
   * of bits 1 and 0.
   * <BR>
   * <BR><TABLE>
   * <TR><TD>Bit 1</TD><TD>Bit 0</TD><TD>Indication Type:</TD></TR>
   * <TR><TD>0</TD><TD>0</TD><TD>Voicemail Message Waiting</TD></TR>
   * <TR><TD>0</TD><TD>1</TD><TD>Fax Message Waiting</TD></TR>
   * <TR><TD>1</TD><TD>0</TD><TD>Electronic Mail Message Waiting</TD></TR>
   * <TR><TD>1</TD><TD>1</TD><TD>Other Message Waiting*</TD></TR>
   * </TABLE>
   * 
   * @see #isIndicationActive()
   * @see #setIndicationType(int)
   * @see #GROUP_MESSAGE_WAITING_DISCARD
   * @see #GROUP_MESSAGE_WAITING_STORE
   * @see #GROUP_MESSAGE_WAITING_STORE_UCS2
   * @return See MESSAGE_WAITING_ field values
   * @throws IllegalStateException If indication not supported by DCS group
   */
  public int getIndicationType() throws IllegalStateException {
    switch (getGroup()) {
    case GROUP_MESSAGE_WAITING_DISCARD:
    case GROUP_MESSAGE_WAITING_STORE:
    case GROUP_MESSAGE_WAITING_STORE_UCS2:
      return value & 0x3; // (B1|B0)
      
    default:
      throw new IllegalStateException(
          "The DCS group does not support message indication!");
    }
    
  }
  
  /* Set methods */
  /**
   * This will set the DCS group and set all other bits to '0' by default.
   * 
   * @param group The group to set the DCS to, see GROUP_ field values
   */
  public void setGroup(final int group) {
    setValue(group);
  }
  
  /**
   * This will set the message coding, see MESSAGE_CODING_ field values.
   * <BR>
   * <BR>This only applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * <BR> - GROUP_MESSAGE_CODING_CLASS (only 7-bit and 8-bit)
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @see #GROUP_MESSAGE_CODING_CLASS
   * @param coding See MESSAGE_CODING_ field values
   * @throws IllegalArgumentException If not corresponding to field values
   * @throws IllegalStateException If value not applicable for the DCS group
   */
  public void setMessageCoding(final int coding) throws IllegalStateException {
    switch (getGroup()) {
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:
      switch (coding) {
      case MESSAGE_CODING_7_BIT_DEFAULT:
      case MESSAGE_CODING_8_BIT_DATA:
      case MESSAGE_CODING_UCS2:
      case MESSAGE_CODING_RESERVED:
        /* Stored in bits 3 and 2. */
        value &= 0xF3; // 0xFF - 0xC (B3|B2)
        value |= coding;
        break;
        
      default: // illegal argument
        throw new IllegalArgumentException(
            "Use DCS MESSAGE_CODING_ field values!");
      }
      break;
      
    case GROUP_MESSAGE_CODING_CLASS:
      switch (coding) {
      case MESSAGE_CODING_7_BIT_DEFAULT:
      case MESSAGE_CODING_8_BIT_DATA:
        value &= N2; // B2
        value |= coding;
        break;
        
      case MESSAGE_CODING_UCS2:
      case MESSAGE_CODING_RESERVED:
        throw new IllegalStateException("UCS2 and RESERVED message"
            + " coding not supported by Message Coding/Class group!");
        
      default: // illegal argument
        throw new IllegalArgumentException(
            "Use DCS MESSAGE_CODING_ field values!");
      }
      break;
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support message coding!");
    }
  }
  
  /**
   * This will set the class meaning, see MESSAGE_CLASS_ field values.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * <BR> - GROUP_MESSAGE_CODING_CLASS
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @see #GROUP_MESSAGE_CODING_CLASS
   * @see #setHasClassMeaning(boolean)
   * @param meaning See MESSAGE_CLASS_ field values
   * @throws IllegalArgumentException If not corresponding to field values
   * @throws IllegalStateException If value not applicable for the DCS group 
   */
  public void setClassMeaning(final int meaning) throws IllegalStateException {
    switch (getGroup()) {
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:
    case GROUP_MESSAGE_CODING_CLASS:
      switch (meaning) {
      case MESSAGE_CLASS_0:
      case MESSAGE_CLASS_1:
      case MESSAGE_CLASS_2:
      case MESSAGE_CLASS_3:
        /* Stored in bits 1 and 0. */
        value &= 0xFC; // 0xFF - 0x3 (B1|B0)
        value |= meaning;
        break;
        
      default: // illegal argument
        throw new IllegalArgumentException(
            "Use DCS MESSAGE_CLASS_ field values!");
      }
      break;
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support message class meaning!");
    }
  }
  
  /**
   * This indicates whether the DCS has a class meaning.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * <BR>
   * <BR>The group GROUP_MESSAGE_CODING_CLASS has class meaning
   * by default and there is no need to indicate this using this
   * method (will result in an IllegalArgumentException).
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @see #setClassMeaning(int)
   * 
   * @param val True if the DCS has class meaning, false otherwise
   * @throws IllegalArgumentException If not corresponding to field values
   * @throws IllegalStateException If value not applicable for the DCS group 
   */
  public void setHasClassMeaning(final boolean val)
  throws IllegalStateException {
    switch (getGroup()) {
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:    
      /* Indication stored in bit 4. */
      if (!val) {
        value &= N4; // B4
      } else {
        value |= B4; // B4
      }
      break;
      
    case GROUP_MESSAGE_CODING_CLASS:
      throw new IllegalArgumentException("DCS: Unneccesary indication,"
          + " the Message Coding/Class group has class meaning by default!");
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support message class meaning!");
    }
  }
  
  /**
   * This indicates whether the DCS has text compression.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_GENERAL_DATA_CODING
   * <BR> - GROUP_AUTOMATIC_DELETION
   * 
   * @see #GROUP_GENERAL_DATA_CODING
   * @see #GROUP_AUTOMATIC_DELETION
   * @see #isTextCompressed()
   * @param val True if the DCS has text compression, false otherwise
   * @throws IllegalStateException If value not applicable for the DCS group 
   */
  public void setTextCompressed(final boolean val)
  throws IllegalStateException {
    switch (value & 0xC0) { // (B7|B6)
    case GROUP_GENERAL_DATA_CODING:
    case GROUP_AUTOMATIC_DELETION:    
      /* Indication stored in bit 5. */
      if (!val) {
        value &= N5; // B5
      } else {
        value |= B5; // B5
      }
      break;
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support text compression!");
    }
  }
  
  /**
   * This will set the message indication to active or inactive.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_MESSAGE_WAITING_DISCARD
   * <BR> - GROUP_MESSAGE_WAITING_STORE
   * <BR> - GROUP_MESSAGE_WAITING_STORE_UCS2
   * 
   * @see #isIndicationActive()
   * @see #GROUP_MESSAGE_WAITING_DISCARD
   * @see #GROUP_MESSAGE_WAITING_STORE
   * @see #GROUP_MESSAGE_WAITING_STORE_UCS2
   * @param val True if message indicaton should be active, false otherwise
   * @throws IllegalStateException If value not applicable for the DCS group
   */
  public void setIndicationActive(final boolean val)
  throws IllegalStateException{
    switch (getGroup()) {
    case GROUP_MESSAGE_WAITING_DISCARD:
    case GROUP_MESSAGE_WAITING_STORE:
    case GROUP_MESSAGE_WAITING_STORE_UCS2:    
      /* Indication stored in bit 3. */
      if (!val) {
        value &= N3; //B3
      } else {
        value |= B3; //B3
      }
      break;
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support message indication!");
    }
  }
  
  /**
   * This will set the message indication type.
   * <BR>
   * <BR>This applies to:
   * <BR> - GROUP_MESSAGE_WAITING_DISCARD
   * <BR> - GROUP_MESSAGE_WAITING_STORE
   * <BR> - GROUP_MESSAGE_WAITING_STORE_UCS2
   * 
   * @see #isIndicationActive()
   * @see #getIndicationType()
   * @see #GROUP_MESSAGE_WAITING_DISCARD
   * @see #GROUP_MESSAGE_WAITING_STORE
   * @see #GROUP_MESSAGE_WAITING_STORE_UCS2
   * @param type The message indicaton type, see MESSAGE_WAITING_ field values
   * @throws IllegalArgumentException If not corresponding to field values
   * @throws IllegalStateException If value not applicable for the DCS group 
   */
  public void setIndicationType(final int type) throws IllegalStateException {
    switch (getGroup()) {
    case GROUP_MESSAGE_WAITING_DISCARD:
    case GROUP_MESSAGE_WAITING_STORE:
    case GROUP_MESSAGE_WAITING_STORE_UCS2:
      switch (type) {
      case MESSAGE_WAITING_ELECTRONIC_MAIL:
      case MESSAGE_WAITING_FAX:
      case MESSAGE_WAITING_OTHER:
      case MESSAGE_WAITING_VOICEMAIL:
        /* Indication type stored in bits 1 and 0. */
        value &= 0xFC; // 0xFF - 0x3 (B1|B0)
        value |= type;
        break;
      
      default: // illegal value
        throw new IllegalArgumentException(
            "Use MESSAGE_WAITING_ field values in DCS!");
      }
      break;
      
    default: // all other groups
      throw new IllegalStateException(
          "The DCS group does not support message indication type!");
    }
  }
  
  /**
   * This will set the DCS value. 
   * 
   * @param value Integer in range 0 - 255, will be masked by 0xFF.
   */
  public void setValue(final int value) {
    this.value = value & ALL;
  }
  
  public String toString() {
    return String.valueOf(value);
  }
}